EP13. AI 애플리케이션 평가 2

LLM 기반 애플리케이션은 모델 단독이 아니라 앱·UI·파이프라인 전체를 평가해야 사업적 가치를 측정할 수 있습니다.

0. 사전 필수 용어 (선행지식)

본 단원 이해에 필요한 핵심 용어 4가지입니다.

  1. LLM (Large Language Model) — 텍스트를 입력받아 다음 토큰을 확률적으로 생성하는 거대 언어 모델. 사전 학습된 일반 지식 위에 프롬프트로 작업을 지시합니다 (예: Claude, GPT, Gemini). 본문 전 구간에서 평가 대상으로 등장합니다.
  2. RAG (Retrieval-Augmented Generation) — 외부 문서를 검색해 LLM 프롬프트에 주입하여 답변을 생성하는 패턴. §4 Step 4, §5 의 다단계 파이프라인 사례입니다.
  3. Ground Truth Dataset (정답 데이터셋) — 모델 출력 평가의 기준이 되는 사람이 검수한 정답 모음. §2, §4 의 도메인 특화 평가 비용 문제와 직결됩니다.
  4. LLM-as-a-Judge — 다른 LLM 에게 출력 품질을 채점시켜 평가를 자동화하는 기법. §4 Step 2 에서 구현합니다.

📚 참고: 깊이 있는 선수 학습은 Anthropic Build with Claude 가이드 또는 Hugging Face LLM Course 참조.

1. 주제 정의

AI 애플리케이션 평가 2 는 LLM 기반 서비스를 모델 단독이 아닌 앱 전체 시스템 관점에서 평가하는 체계입니다. 도메인 특화 능력·앱 수준 일반 평가·수행성·비용/속도 4개 축으로 측정합니다.

핵심 아이디어: 모델 점수 ≠ 서비스 가치. 추가 시스템(메모리·UI·파이프라인)이 보완하는 가치를 평가에 포함해야 사업적 성공을 측정할 수 있습니다.

2. 풀려는 문제

LLM 기반 서비스가 직면하는 4가지 평가 난제입니다.

  • 문제 1 — 도메인 가치 측정 불가: 일반 벤치마크(MMLU·HellaSwag 등)는 "주가 25% 적중" 같은 사업적 핵심 가치를 측정하지 못합니다.
  • 문제 2 — 정답 데이터셋 비용 폭증: 광범위한 Ground Truth 구축에 수억 원·수개월 단위 자원이 소요됩니다.
  • 문제 3 — 응답 지연 (≥30초): LLM 호출은 본질적으로 느려 레거시 0.1초 응답 기준을 충족할 수 없습니다.
  • 문제 4 — 다단계 파이프라인 원인 규명 곤란: RAG 결과가 개선돼도 청킹·임베딩·리트리벌·리랭커 중 어느 단계 덕분인지 분리할 수 없습니다.

💡 실무 노하우: 정답 데이터셋 비용이 막힐 때 가장 흔한 우회는 LLM-as-a-Judge + 일부 수동 검수 샘플링 입니다. 100% 데이터셋 대신 5~10% 수동 검수로 Judge 의 신뢰도를 calibrate 합니다.

3. 핵심 개념·구조

LLM 앱 평가는 다음 4개 축으로 구성됩니다.

  • 도메인 특화 능력 (Domain-Specific) — 고객 핵심 가치와 직결되는 비즈니스 지표. 보통 광범위한 정답 데이터셋이 필요.
  • 앱 수준 일반 평가 (App-Level General) — 모델 평가 항목을 앱 출력에 다시 적용. 추가 시스템 덕분에 모델 단독보다 점수가 높음.
  • 수행성 (Performance/UX) — 부정확한 사용자 입력을 LLM 정규화·메모리·범용 컨텍스트로 보정하는 능력.
  • 비용·속도 (Cost & Latency) — 외부 API·자체 모델 비용 최적화 + 응답 지연을 UI 로 보완하는 기획.
사용자 입력
   ↓
[1차 보정: LLM 정규화 + 메모리]   ← 수행성 평가
   ↓
[RAG 파이프라인: split → parse → chunk → embed → retrieve → rerank]   ← 단계별 평가
   ↓
[LLM 호출 (Claude/GPT)]   ← 모델 평가
   ↓
[스트리밍 출력 + 부분 렌더링]   ← UI 보완 평가
   ↓
[최종 결과]   ← 앱 수준 일반 평가 + 도메인 특화 평가

4. 구현 가이드 (Do It Yourself)

시작 전 (Before you begin)

이 섹션을 완료하면 LLM-as-a-Judge 자동 평가 루프와 RAG 단계별 평가 정의를 직접 구현할 수 있습니다.

선수 조건: - Python 3.10+ - pip install anthropic ragas datasets - 환경 변수 ANTHROPIC_API_KEY 설정

소요 시간: 약 40분.

Step 1 — Anthropic SDK 환경 구성

목표: 평가에 사용할 LLM 클라이언트를 준비합니다.

다음 코드를 eval_setup.py 에 추가합니다.

import os
from anthropic import Anthropic

client = Anthropic()  # ANTHROPIC_API_KEY 자동 로드

JUDGE_MODEL = "claude-sonnet-4-6"

Anthropic() 인스턴스는 환경 변수 ANTHROPIC_API_KEY 를 자동 인식합니다.

⚠️ 주의: API 키를 코드에 직접 박지 마세요. .env + python-dotenv 또는 OS 환경 변수만 사용합니다. 노출 시 즉시 console.anthropic.com 에서 revoke 합니다.

💡 실무 노하우: Judge 모델은 평가 대상보다 동급 이상을 사용합니다. Haiku 출력을 Sonnet 으로 채점하는 것은 OK, 반대는 신뢰도가 하락합니다.

📚 참고: Anthropic Python SDK Quickstart.

확인: python -c "from eval_setup import client; print(client)" 가 에러 없이 실행됩니다.


Step 2 — LLM-as-a-Judge 함수 작성

목표: 임의 응답을 1~5점으로 채점하는 함수를 만듭니다.

다음 코드를 judge.py 에 추가합니다.

from eval_setup import client, JUDGE_MODEL

JUDGE_SYSTEM = (
    "당신은 LLM 출력 품질 평가관입니다. "
    "정확성·관련성·완결성을 1~5점으로 채점하고 사유 1줄을 출력하세요. "
    "출력 형식: SCORE=<n>; REASON=<사유>"
)

def judge(question: str, answer: str) -> dict:
    resp = client.messages.create(
        model=JUDGE_MODEL,
        max_tokens=256,
        system=JUDGE_SYSTEM,
        messages=[{
            "role": "user",
            "content": f"질문:\n{question}\n\n응답:\n{answer}",
        }],
    )
    text = resp.content[0].text
    score = int(text.split("SCORE=")[1].split(";")[0].strip())
    return {"score": score, "raw": text}

client.messages.create 로 Judge 모델을 호출하고 응답에서 SCORE= 토큰을 파싱합니다.

⚠️ 주의: 파싱 형식이 깨질 수 있으므로 실서비스는 정규식 + try/except 로 방어하거나 tool use 로 구조화된 출력을 강제하세요.

💡 실무 노하우: 5점 척도는 분산이 작아 1·3·5 (Bad/OK/Good) 3점 척도가 노이즈에 더 강합니다.

확인: judge("1+1=?", "2"){'score': 5, ...} 부근을 반환합니다.


Step 3 — 도메인 데이터셋 평가 루프

목표: 정답 데이터셋을 순회하며 평균 점수를 산출합니다.

다음 코드를 run_eval.py 에 추가합니다.

from judge import judge

dataset = [
    {"q": "AAPL 다음 분기 EPS 추정 범위?", "expected": "약 1.65~1.72달러"},
    {"q": "NVDA 데이터센터 매출 추세?", "expected": "전년대비 +200% 성장 지속"},
]

def evaluate_app(app_fn):
    scores = []
    for row in dataset:
        ans = app_fn(row["q"])
        result = judge(row["q"], ans)
        scores.append(result["score"])
    return sum(scores) / len(scores)

app_fn 자리에 본인의 RAG 체인 또는 LLM 호출 함수를 주입합니다.

💡 실무 노하우: 데이터셋 100건 미만이면 분산이 크므로 부트스트랩 신뢰구간(scipy.stats.bootstrap)을 함께 보고합니다.

📚 참고: 자동 평가 메트릭 라이브러리 RAGAS, DeepEval.

확인: evaluate_app(my_chain) 이 1.0~5.0 사이 float 를 반환합니다.


Step 4 — 단계별 평가 정의 (RAG 파이프라인)

목표: 최종 결과뿐 아니라 RAG 각 단계 산출물을 개별 평가합니다.

다음 코드를 pipeline_eval.py 에 추가합니다.

STAGE_METRICS = {
    "chunking":   lambda chunks: len(chunks) > 0 and all(50 < len(c) < 1500 for c in chunks),
    "retrieval":  lambda hits, gt_doc_id: gt_doc_id in [h.id for h in hits[:5]],
    "reranking":  lambda hits, gt_doc_id: hits[0].id == gt_doc_id,
    "generation": lambda q, a: judge(q, a)["score"] >= 4,
}

각 단계가 독립적으로 통과/실패를 판단하므로 어느 단계가 최종 결과에 기여했는지 추적할 수 있습니다.

⚠️ 주의: 단계 간 "궁합" 효과가 있어 단일 단계 점수 합 ≠ 최종 점수. A/B 테스트 시 한 단계만 바꾸세요.

💡 실무 노하우: 단계별 평가는 초기 구축 비용이 크지만 장기적으로 개선 속도가 N배. 평가 환경에 LangSmith 등 trace 도구를 함께 도입하면 가시성이 크게 향상됩니다.

확인: 한 단계 파라미터(예: chunk_size)만 바꿔 실행했을 때 해당 단계 metric 만 변화해야 합니다.


Step 5 — 동작 확인 (테스트)

from eval_setup import client
from run_eval import evaluate_app

def baseline_chain(q: str) -> str:
    r = client.messages.create(
        model="claude-sonnet-4-6", max_tokens=512,
        messages=[{"role": "user", "content": q}],
    )
    return r.content[0].text

print(f"App score: {evaluate_app(baseline_chain):.2f}/5.0")

예상 출력:

App score: 3.85/5.0

5. 적용 사례 (공신력 오픈소스)

  • LangChain (https://github.com/langchain-ai/langchain) — Chain·Agent 평가 hook + LangSmith 통합 trace.
  • LlamaIndex (https://github.com/run-llama/llama_index) — RAG 인덱스·리트리벌 단계별 evaluator 내장.
  • Anthropic Python SDK (https://github.com/anthropics/anthropic-sdk-python) — Judge 모델 호출 표준 SDK.
  • OpenAI Python SDK (https://github.com/openai/openai-python) — 비교군 Judge 호환.
  • HuggingFace Transformers (https://github.com/huggingface/transformers) — 임베딩·리랭커 모델 풀.
  • vLLM (https://github.com/vllm-project/vllm) — Self-hosted 평가 시 throughput 최적화.
  • LiteLLM (https://github.com/BerriAI/litellm) — 멀티-벤더 Judge 통합 라우팅.
  • RAGAS (https://github.com/explodinggradients/ragas) — faithfulness, answer_relevancy 등 RAG 전용 메트릭.
  • DeepEval (https://github.com/confident-ai/deepeval) — pytest 스타일 LLM 평가 프레임워크.

📚 참고: 위 OSS 는 모두 GitHub stars ≥ 5K 또는 벤더 공식 SDK 입니다.

💡 실무 노하우: RAGAS + LangSmith 조합이 RAG 평가의 사실상 표준. Judge LLM 은 Anthropic SDK 로 직접 호출하면 응답 형식 컨트롤이 더 정밀합니다.

6. 핵심 원리

가장 중요한 두 원리입니다.

  1. 시스템 평가는 시스템화한다 — 수동 평가는 평가하지 않는 것과 같음. NLP 계열은 수십~수백 번 반복이 기본이므로 자동화 없이는 회귀를 탐지할 수 없습니다.
  2. 앱 가치 = 모델 + 추가 시스템 — 모델 부족함을 메모리·RAG·UI 가 보완하므로 평가 대상은 항상 최종 사용자 경험.

7. 변형·확장

  • Streaming 평가 — 부분 렌더링 응답의 일관성·완결성을 토큰 단위로 평가.
  • Multi-turn 평가 — 대화 히스토리 보존 능력 측정.
  • A/B 라이브 평가 — 사용자 클릭률·체류 시간을 도메인 metric 으로 채택.
  • Adversarial 평가 — 의도적으로 잘못된 입력에 대한 robustness 검증.

8. 다른 도구·접근과의 비교 (3-way)

항목 RAGAS DeepEval LangSmith
메트릭 종류 faithfulness·context_precision G-Eval·toxicity·hallucination LLM-as-Judge + Trace
통합 환경 LangChain·LlamaIndex pytest LangChain 네이티브
추가 비용 Judge LLM 호출분 Judge LLM 호출분 Hosted 유료 (Self-host 무료)
강점 RAG 특화 메트릭 CI 통합 친화 Trace 시각화
  • vs RAGAS — RAG 특화 단계별 메트릭이 풍부합니다.
  • vs DeepEvalpytest 친화로 CI 자동화가 쉽습니다.
  • vs LangSmith — 운영 trace + 평가 UI 가 통합되어 운영자 친화적입니다.

9. 한계·트레이드오프

  1. Judge 모델 편향 — Judge 가 더 길거나 자기 스타일을 선호하는 "verbosity bias".
  2. 비용 폭증 — 데이터셋 1000건 × 단계 5개 = 5000회 Judge 호출 → 평가 1회당 수십 달러.
  3. 단계 간 궁합 효과 — 단일 단계 최적이 전체 최적과 불일치할 수 있음.
  4. 데이터셋 신선도 — 도메인 변화 시 정답이 stale 화되어 재구축 비용 발생.

10. 최신 권장 패턴 (2026-05 기준)

  • Structured Output (JSON Mode) — Judge 응답을 {"score": int, "reason": str} 스키마로 강제하여 파싱 실패를 0 으로.
  • Anthropic Tool Use — Judge 결과를 도구 호출로 받으면 형식 violation 차단.
  • Prompt Caching + Batch API — Anthropic prompt caching + batch API 로 동일 시스템 프롬프트 비용을 크게 절감.
  • MCP (Model Context Protocol) — 외부 평가 도구를 모델에 표준화 노출.
  • Trace-based Eval — LangSmith·Langfuse trace 위에 자동 metric 적용.

💡 실무 노하우: Judge 모델은 caching 으로 시스템 프롬프트 비용이 거의 0 에 수렴. 평가 데이터셋이 커질수록 ROI 가 큽니다.

11. 메타인지 자기평가

본인 서비스 적용 가능성 검증 절차입니다.

Step 1 — 현재 상태 점검

# 평가 코드 존재 여부
grep -r "evaluate\|judge\|score" tests/ src/ | wc -l
# 평가 자동화 CI 진단
find .github/workflows -name "*.yml" | xargs grep -l "eval"

Step 2 — 적용 가능성 평가 - 도메인 핵심 가치가 1줄로 정의되어 있는가? - 데이터셋 30건 이상 확보 가능한가? - Judge 호출 비용을 월 운영비에 반영했는가? - 다단계 파이프라인이 있다면 단계별 trace 가 가능한가?

Step 3 — 점진 적용 1. Step 2~3 부터 도입 (최종 결과 LLM-as-Judge 만). 2. 데이터셋을 50건 → 300건으로 확장. 3. 1개 단계 metric (예: recall@5) 추가. 4. 단계별 metric 을 점진 추가. 5. CI 에 평가 게이트 연결 (점수 회귀 시 PR 차단).

난이도
에피소드
질문
카드를 로딩 중...
답변

클릭하거나 Space를 눌러 뒤집기

0 / 0
학습 진도 0%
이동   Space 뒤집기   R 셔플